package com.irdstudio.efp.batch.service.util;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;

import com.irdstudio.efp.batch.service.domain.TxtFileLoadBean;

/**
 * 开发人员：chenxuan
 * 创建日期：2019/5/29 11:15
 * 功能描述：使用多线程处理数据加工
 * step：1、使用TxtFileLoadPlugin从文本加载数据映射为List<> 2、分割List通过从线程池获取线程去运行；
 *
 * @version 0.1
 */
public class DueDataPlugin {
    /**
     * 文件URL
     */
    private String fileUrl;
    /**
     * 分隔符
     */
    private String dataSplit;
    /**
     * 编码类型
     */
    private String fileCharset;
    /**
     * 是否去首行
     */
    private int isFirstline;
    /**
     * 每次读取条数
     */
    private int readCount;
    /**
     * 线程数
     */
    private int threadCount;
    /**
     * 文件行 映射实体类
     */
    private TxtFileLoadBean txtFleLoandDemoBean;
    /**
     * 具体执行 业务逻辑的类
     */
    private DueDataTaskThread thread;
    /**
     * 线程名称 字符串
     */
    private String threadNameStr;

    public DueDataPlugin(String fileUrl, String dataSplit, String fileCharset, int isFirstline, int readCount, int threadCount, TxtFileLoadBean txtFleLoandDemoBean, DueDataTaskThread thread) {
        this.fileUrl = fileUrl;
        this.dataSplit = dataSplit;
        this.fileCharset = fileCharset;
        this.isFirstline = isFirstline;
        this.readCount = readCount;
        this.threadCount = threadCount;
        this.txtFleLoandDemoBean = txtFleLoandDemoBean;
        this.thread = thread;
        this.threadNameStr = thread.getClass().getName();
    }

    public void doTask() {
        try {
            TxtFileLoadPlugin txtFileLoadPlugin = new TxtFileLoadPlugin(fileUrl, dataSplit, fileCharset, isFirstline, readCount);
            List<TxtFileLoadBean> testList = txtFileLoadPlugin.run(txtFleLoandDemoBean);
            dueData(testList, threadCount);
            if (testList.size() != 0) {
                while (!testList.get(testList.size() - 1).isReadedComplete) {
                    txtFileLoadPlugin.setFirstRead(false);
                    testList = txtFileLoadPlugin.run(txtFleLoandDemoBean);
                    if (testList.size() == 0) {
                        break;
                    }
                    dueData(testList, threadCount);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //ConcurrentMap fd =   TThreadPools.getLocalStoreMap();
            for (int i = 0; i < threadCount; i++)
                TThreadPools.showdownThreadPool(threadNameStr + i);
        }
    }

    /**
     * 处理数据
     */
    public void dueData(List<TxtFileLoadBean> testList, int threadCount) throws Exception {
        ExecutorService threadPool = null;
        CountDownLatch countDownLatch = new CountDownLatch(threadCount);
        if (threadCount != 1 || threadCount != 0) {
            List<List<TxtFileLoadBean>> lists = avarageAssign(testList, threadCount);
            for (int i = 0; i < threadCount; i++) {
                threadPool = TThreadPools.getThreadPool(threadNameStr + i);
                if (threadPool == null || threadPool.isTerminated()) {
                    threadPool = TThreadPools.getThreadPool(threadNameStr + i);
                }
                DueDataTaskThread dueDataTaskThread = thread.clone();
                dueDataTaskThread.setTxtFileLoadBeans(lists.get(i));
                dueDataTaskThread.setCountDownLatch(countDownLatch);
                threadPool.execute(dueDataTaskThread);
            }
        } else {
            DueDataTaskThread dueDataTaskThread = thread.clone();
            dueDataTaskThread.setTxtFileLoadBeans(testList);
            dueDataTaskThread.setCountDownLatch(countDownLatch);
            threadPool.execute(dueDataTaskThread);
        }
        countDownLatch.await();

    }

    public static <T> List<List<T>> avarageAssign(List<T> source, int n) {
        List<List<T>> result = new ArrayList<List<T>>();
        int remaider = source.size() % n;
        int number = source.size() / n;
        int offset = 0;
        for (int i = 0; i < n; i++) {
            List<T> value = null;
            if (remaider > 0) {
                value = source.subList(i * number + offset, (i + 1) * number + offset + 1);
                remaider--;
                offset++;
            } else {
                value = source.subList(i * number + offset, (i + 1) * number + offset);
            }
            result.add(value);
        }
        return result;
    }


    public String getFileUrl() {
        return fileUrl;
    }

    public void setFileUrl(String fileUrl) {
        this.fileUrl = fileUrl;
    }

    public String getDataSplit() {
        return dataSplit;
    }

    public void setDataSplit(String dataSplit) {
        this.dataSplit = dataSplit;
    }

    public String getFileCharset() {
        return fileCharset;
    }

    public void setFileCharset(String fileCharset) {
        this.fileCharset = fileCharset;
    }

    public int getIsFirstline() {
        return isFirstline;
    }

    public void setIsFirstline(int isFirstline) {
        this.isFirstline = isFirstline;
    }
    public int getReadCount() {
        return readCount;
    }

    public void setReadCount(int readCount) {
        this.readCount = readCount;
    }

    public int getThreadCount() {
        return threadCount;
    }

    public void setThreadCount(int threadCount) {
        this.threadCount = threadCount;
    }

    public TxtFileLoadBean getTxtFleLoandDemoBean() {
        return txtFleLoandDemoBean;
    }

    public void setTxtFleLoandDemoBean(TxtFileLoadBean txtFleLoandDemoBean) {
        this.txtFleLoandDemoBean = txtFleLoandDemoBean;
    }
}
